package com.berje.vkalarm;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.text.format.Time;
import android.util.Log;
import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.berje.vkalarm.fragments.AlarmFragment;
import com.berje.vkalarm.fragments.DownloadFragment;
import com.berje.vkalarm.fragments.IOnAlarmClickListener;
import com.berje.vkalarm.vksdk.Api;
import com.berje.vkalarm.vksdk.KException;
import com.berje.vkalarm.vksdk.model.Audio;
import com.berje.vkalarm.vksdk.model.Group;
import com.berje.vkalarm.vksdk.model.GroupAudioNewsItem;
import ua.com.vassiliev.androidfilebrowser.FileBrowserActivity;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.Calendar;
import java.util.List;

public class VkAlarmMainActivity extends SherlockFragmentActivity implements IOnDownloadClickListener, IOnAlarmClickListener {

    private static final int REQUEST_LOGIN = 1;
    private static final int REQUEST_CODE_PICK_DIR = 2;
    private final static String TAG = "vkalarm-main";
    private Account account = new Account();
    private Api api;
    private ProgressDialog mProgressDialog;
    private DownloadFragment downloadFragment;
    private AlarmFragment alarmFragment;
    private List<Group> groups;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final ActionBar bar = getSupportActionBar();
        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        bar.setTitle("Music Group Tool");

        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setMessage("Downloading...");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

        account.restore(this);
        if (account.getAccess_token() != null) {
            Log.d(TAG, "Saves token: " + account.getAccess_token());
            api = new Api(account.getAccess_token(), Constants.API_ID);
            onVkApiOk();
        } else {
            startLoginActivity();
        }

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // spinnerAdapter.clearCash();
    }

    private void startLoginActivity() {
        Log.d(TAG, "startLoginActivity()");
        Intent intent = new Intent();
        intent.setClass(this, LoginActivity.class);
        startActivityForResult(intent, REQUEST_LOGIN);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult()");
        if (requestCode == REQUEST_LOGIN) {
            if (resultCode == RESULT_OK) {
                account.setAccess_token(data.getStringExtra("token"));
                account.setUser_id(data.getLongExtra("user_id", 0));
                account.save(this);
                Log.d(TAG, "account: " + account.getAccess_token() + " " + account.getUser_id());
                api = new Api(account.getAccess_token(), Constants.API_ID);
                onVkApiOk();
            }
        } else if (requestCode == REQUEST_CODE_PICK_DIR) {
            if (resultCode == RESULT_OK) {
                String newDir = data.getStringExtra(ua.com.vassiliev.androidfilebrowser.FileBrowserActivity.returnDirectoryParameter);
                boolean createInnerDir = data.getBooleanExtra(FileBrowserActivity.returnDirectoryCreateInnerDirParameter, false);

                Log.d(TAG, "dir: " + newDir + " createInnerDir: " + createInnerDir);
                downloadCurrentAudioPost(newDir, createInnerDir);
            } else {
                Toast.makeText(this, "Received NO result from file browser", Toast.LENGTH_LONG).show();
            }

        }
    }

    private void downloadCurrentAudioPost(final String dir, boolean createInnerDir) {
        Log.d(TAG, "downloadCurrentAudioPost to " + dir);
        Log.d(TAG, "currentAudioPostIndex: " + downloadFragment.getCurrentAudioPostIndex());

        GroupAudioNewsItem cani = downloadFragment.getAudioPosts().get(downloadFragment.getCurrentAudioPostIndex());

        Group g = downloadFragment.getCurrentGroup();


        String dirPath = dir;
        if (createInnerDir) {
            Time now = new Time();
            now.setToNow();
            String innerDir = now.format("%Y-%m-%dT%H-%M-%S");

            if (g != null) {
                String name = g.getName();

                if (name != null) {
                    if (name.length() > 64)
                        name = name.substring(0, 63);
                    innerDir = innerDir + "-" + name;
                }
            }

            Log.d(TAG, "innerDir: " + innerDir);
            dirPath = dir + "/" + innerDir;
        }
        final String fullPath = dirPath;

        File file = new File(fullPath);

        if (!file.exists()) {
            Log.d(TAG, "try to make : " + fullPath);
            file.mkdir();
        }

        Log.d(TAG, "current Audio News Item: " + cani);
        if (cani.getAudios() != null && cani.getAudios().size() > 0) {
            Log.d(TAG, "Audios: ");
            int i = 0;
            for (Audio a : cani.getAudios()) {
                Log.d(TAG, i + " audio: " + a);
                i++;
            }

            final List<Audio> in = cani.getAudios();
            new AsyncTask<Void, ProgressParam, List<Audio>>() {

                @Override
                protected void onPreExecute() {
                    super.onPreExecute();
                    mProgressDialog.show();
                }

                @Override
                protected void onProgressUpdate(ProgressParam... params) {
                    super.onProgressUpdate(params);
                    mProgressDialog.setMessage(params[0].progressMessage);
                    mProgressDialog.setProgress(params[0].progressInt);
                }

                @Override
                protected List<Audio> doInBackground(Void... params) {
                    List<Audio> filledAudios = null;
                    try {
                        ProgressParam pp = new ProgressParam();

                        filledAudios = api.getFilledAudios(in);

                        int i = 0;
                        int size = filledAudios.size();
                        for (Audio fa : filledAudios) {
                            i++;
                            pp.progressMessage = "Downloading " + fa.getArtist() + "-" + fa.getTitle() + " (" + i + "/" + size + ")";
                            Log.d(TAG, fa.getArtist() + " " + fa.getTitle() + " -> " + fa.getUrl());
                            URL url = new URL(fa.getUrl());
                            URLConnection connection = url.openConnection();
                            connection.connect();
                            // this will be useful so that you can show a
                            // typical 0-100% progress bar
                            int fileLength = connection.getContentLength();
                            // download the file
                            InputStream input = new BufferedInputStream(url.openStream());

                            String toPath = fullPath + "/" + fa.getArtist() + " " + fa.getTitle() + ".mp3";
                            Log.d(TAG, "toPath: " + toPath);
                            OutputStream output = new FileOutputStream(toPath);

                            byte data[] = new byte[1024];
                            long total = 0;
                            int count;
                            while ((count = input.read(data)) != -1) {
                                total += count;
                                // publishing the progress....
                                pp.progressInt = (int) (total * 100 / fileLength);
                                publishProgress(pp);
                                output.write(data, 0, count);
                            }

                            output.flush();
                            output.close();
                            input.close();

                        }

                    } catch (Exception e) {
                        Log.e(TAG, "Error get post audios", e);
                    }
                    return filledAudios;
                }

                @Override
                protected void onPostExecute(List<Audio> audios) {
                    super.onPostExecute(audios);
                    mProgressDialog.hide();

                    // TODO: open folder in mp3 player
                    // Log.d(TAG, "mp3 folder uri: " + fullPath);
                    // Uri uri = Uri.parse(fullPath);
                    //
                    // Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                    // intent.setType("audio/*");
                    //
                    // startActivity(intent);

                }

            }.execute();

        }

    }

    @Override
    public void onVkResponseError(KException ke) {
        Log.e(TAG, "onVkResponseError: " + ke);
        startLoginActivity();
    }

    private void onVkApiOk() {
        Log.d(TAG, "onVkApiOk()");
        new AsyncTask<Account, Void, List<Group>>() {

            @Override
            protected List<Group> doInBackground(Account... params) {
                Account a = params[0];
                List<Group> groups = null;
                try {
                    groups = api.getUserGroups(a.getUser_id());
                } catch (KException ke) {
                    Log.e(TAG, "KException on getUserGroups");
                    onVkResponseError(ke);
                } catch (Exception e) {
                    Log.e(TAG, "Error getting groups for " + a, e);
                }

                if (groups != null && groups.size() > 0) {
                    Utils.getGroupBitmap(groups.get(groups.size() / 2));
                }
                return groups;
            }

            @Override
            protected void onPostExecute(List<Group> groups) {
                super.onPostExecute(groups);
                onGroups(groups);
            }

        }.execute(account);

    }

    private void onGroups(List<Group> groups) {
        if (groups == null)
            return;

        this.groups = groups;
        downloadFragment = new DownloadFragment(groups);
        alarmFragment = new AlarmFragment(groups);

        final ActionBar bar = getSupportActionBar();
        bar.addTab(bar.newTab().setText("Download music posts").setTabListener(new TabListener(downloadFragment)));
        bar.addTab(bar.newTab().setText("Alarm music group").setTabListener(new TabListener(alarmFragment)));
        bar.setSelectedNavigationItem(0);
    }

    public List<Group> getGroups() {
        return groups;
    }

    @Override
    public void onDownloadClick() {

        Log.d(TAG, "Start browsing button pressed");
        Intent fileExploreIntent = new Intent(ua.com.vassiliev.androidfilebrowser.FileBrowserActivity.INTENT_ACTION_SELECT_DIR, null, this,
                ua.com.vassiliev.androidfilebrowser.FileBrowserActivity.class);

        // If the parameter below is not provided the Activity will try to start
        // from sdcard(external storage),
        // if fails, then will start from roor "/"
        // Do not use "/sdcard" instead as base address for sdcard use
        // Environment.getExternalStorageDirectory()
        // fileExploreIntent.putExtra(
        // ua.com.vassiliev.androidfilebrowser.FileBrowserActivity.startDirectoryParameter,
        // "/sdcard"
        // );

        startActivityForResult(fileExploreIntent, REQUEST_CODE_PICK_DIR);
    }

    @Override
    public void onApplyButtonClick(int h, int m) {
        Log.d(TAG, "onApplyButton " + h + ":" + m);
        Group g = downloadFragment.getCurrentGroup();
        // Integer h2 = hours.getCurrentItem();
        // Integer m2 = mins.getCurrentItem();
        // Log.d(TAG, "Apply h: " + h2 + " m: " + m2 + " g: " + g);
        account.setAlarm_gid(g.getGid());
        account.save(this);
        AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(this, AlarmActivity.class);
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.putExtra("gid", g.getGid());
        PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);

        Time time = new Time();
        time.setToNow();

        Calendar current = Calendar.getInstance();

        Log.d(TAG, "current " + current.get(Calendar.HOUR_OF_DAY) + ":" + current.get(Calendar.MINUTE));

        Calendar alarm = Calendar.getInstance();
        alarm.set(Calendar.HOUR_OF_DAY, h);
        alarm.set(Calendar.MINUTE, m);

        if (alarm.before(current)) {
            alarm.add(Calendar.DAY_OF_MONTH, 1);
            Log.d(TAG, "tommorow!");
        }
        Log.d(TAG, "diff: " + (alarm.getTimeInMillis() - current.getTimeInMillis())/1000);
        alarmManager.set(AlarmManager.RTC_WAKEUP, alarm.getTimeInMillis(), pi);
    }

    public Api getApi() {
        return api;
    }

    public void setApi(Api api) {
        this.api = api;
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        //No call for super(). Bug on API Level > 11.
    }

    public static class TabListener implements ActionBar.TabListener {
        private Fragment mFragment;

        public TabListener(Fragment fragment) {
            this.mFragment = fragment;
        }

        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            if (mFragment != null)
                ft.replace(R.id.fragment_content, mFragment);
        }

        @Override
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        }

        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {
        }
    }

    private class ProgressParam {
        public Integer progressInt;
        public String progressMessage;
    }

}
